#include "stdafx.h"
#include "DataManager.h"
#include "DL_Debug.h"
#include "ExtendedString.h"
#include "FileHelperFunctions.h"
#include "StringUtilities.h"

Utilities::DataManager::DataManager()
{
	myParameters.Init(10, 10);
}

Utilities::DataManager::~DataManager()
{

}

void Utilities::DataManager::AddParameter(const std::string& aParameterName, bool& aParameter)
{
	myParameters.Add(Parameter());
	myParameters[myParameters.Count() - 1].type = Parameter::BOOL;
	AddParameter(aParameterName, reinterpret_cast<void*>(&aParameter));
}

void Utilities::DataManager::AddParameter(const std::string& aParameterName, Vector2f& aParameter)
{
	myParameters.Add(Parameter());
	myParameters[myParameters.Count() - 1].type = Parameter::VECTOR2F;
	AddParameter(aParameterName, reinterpret_cast<void*>(&aParameter));
}

bool Utilities::DataManager::ReadData(const std::string& aFileName)
{
	OS::File file;
	DL_CHK_ERROR(file.Open(aFileName, OS::READ), ExtendedString("Failed to open \"") << aFileName << "\". Nothing was read");
	
	if(file.IsOpen())
	{
		return ReadData(file);
	}
	
	return false;
}

bool Utilities::DataManager::ReadData(OS::File& aFile)
{
	DL_CHK_ERROR(aFile.IsOpen(), "File is not open. Nothing was read");

	Utilities::GrowingArray<Parameter> readParameters(myParameters.Count(), 1);

	if(aFile.IsOpen())
	{
		std::string cmd;
		while(aFile.Eof() == false)
		{
			if(aFile.ReadWord(cmd) == false)
			{
				break;
			}

			if(cmd.size() >= 2 && cmd.substr(0, 2) == "//")
			{
				aFile.GoToNewLine();
				continue;
			}

			ToLower(cmd);
			for(unsigned int i = 0; i < myParameters.Count(); i++)
			{
				if(cmd == GetToLower(myParameters[i].name))
				{
					ReadParameter(myParameters[i], aFile);
					readParameters.Add(myParameters[i]);
					myParameters.RemoveCyclicAtIndex(i);
					break;
				}
			}
		}

		if(myParameters.Count() > 0)
		{
			DL_PRINT(ExtendedString("Note: All expected parameters could not be found in \"") << aFile.GetFileName() << "\". Missing parameters:");
			DL_INCREASETAB;
			for(unsigned int i = 0; i < myParameters.Count(); i++)
			{
				DL_PRINT(myParameters[i].name);
			}
			DL_DECREASETAB;
		}

		while(readParameters.Count() > 0)
		{
			myParameters.Add(readParameters[readParameters.Count() - 1]);
			readParameters.RemoveCyclicAtIndex(readParameters.Count() - 1);
		}

		return true;
	}

	return false;
}

bool Utilities::DataManager::WriteData(const std::string& aFileName)
{
	OS::File file;
	DL_CHK_ERROR(file.Open(aFileName, OS::WRITE), ExtendedString("Failed to open \"") << aFileName << "\". Nothing was written");

	if(file.IsOpen())
	{
		return WriteData(file);
	}

	return false;
}

bool Utilities::DataManager::WriteData(OS::File& aFile)
{
	DL_CHK_ERROR(aFile.IsOpen(), "File is not open. Nothing was written");
	if(aFile.IsOpen())
	{
		for(unsigned int i = 0; i < myParameters.Count(); i++)
		{
			WriteParameter(myParameters[i], aFile);
			aFile.WriteString("\n");
		}
	}

	return true;
}

void Utilities::DataManager::AddParameter(const std::string& aParameterName, void* aData)
{
	myParameters[myParameters.Count() - 1].name = aParameterName;
	myParameters[myParameters.Count() - 1].data = aData;
}

void Utilities::DataManager::ReadParameter(Parameter& aParameter, OS::File& aFile)
{
	switch(aParameter.type)
	{
	case Parameter::BOOL:
		aFile.ReadBool(*(reinterpret_cast<bool*>(aParameter.data)));
		break;
	case Parameter::VECTOR2F:
		ReadVector(aFile, *(reinterpret_cast<Vector2f*>(aParameter.data)));
		break;
	}
}

void Utilities::DataManager::WriteParameter(Parameter& aParameter, OS::File& aFile)
{
	aFile.WriteString(aParameter.name);
	aFile.WriteString(" ");
	switch(aParameter.type)
	{
	case Parameter::BOOL:
		aFile.WriteBool(*(reinterpret_cast<bool*>(aParameter.data)));
		break;
	case Parameter::VECTOR2F:
		WriteVector(aFile, *(reinterpret_cast<Vector2f*>(aParameter.data)));
		break;
	}
}
